﻿using MediatR;
using Practice.Common.Domains;
using Practice.Common.Dto;
using Practice.Common.Infrastructure.Interfaces;

namespace Practice.API.Application.Commands.Main
{
    public class MainPermissionHandler:IRequestHandler<MainPermissionCommand,Result>
    {
        public readonly IBaseRepository<Users> UsersRepository;
        public readonly IBaseRepository<UserRole> UserRoleRepository;
        public readonly IBaseRepository<Role> RoleRepository;
        public readonly IBaseRepository<RolePermission> RolePermissionRepository;
        public readonly IBaseRepository<Permission> PermissionRepository;

        public MainPermissionHandler(IBaseRepository<Users> usersRepository, IBaseRepository<UserRole> userRoleRepository, IBaseRepository<Role> roleRepository, IBaseRepository<RolePermission> rolePermissionRepository, IBaseRepository<Permission> permissionRepository)
        {
            UsersRepository = usersRepository;
            UserRoleRepository = userRoleRepository;
            RoleRepository = roleRepository;
            RolePermissionRepository = rolePermissionRepository;
            PermissionRepository = permissionRepository;
        }

        public async Task<Result> Handle(MainPermissionCommand request, CancellationToken cancellationToken)
        {
            var result = new Result();
            var list = from a in UsersRepository.GetAll()
                       join b in UserRoleRepository.GetAll() on a.UserId equals b.UserId
                       join c in RoleRepository.GetAll() on b.RoleId equals c.RoleId
                       join d in RolePermissionRepository.GetAll() on c.RoleId equals d.RoleId
                       join e in PermissionRepository.GetAll() on d.PermissionId equals e.PermissionId
                       group e by new { a.UserId, e.PermissionName } into g
                       select new UserPermissionDto()
                       {
                           UserId = g.Key.UserId,
                           PermissionName = string.Join(',', g.Select(x => x.PermissionName))
                       };
            if (request.UserId != 0)
            {
                list = list.Where(x => x.UserId == request.UserId);
            }
            result.Data = list;
            return result;
        }
    }
    public class UserPermissionDto
    {
        public int UserId { get; set; }
        public string PermissionName { get; set; }
    }
}
